package com.dahaiwuliang.code.controller;



import com.dahaiwuliang.code.lucene.ArticleIndex;
import com.dahaiwuliang.code.pojo.Article;
import com.dahaiwuliang.code.pojo.Message;
import com.dahaiwuliang.code.pojo.User;
import com.dahaiwuliang.code.pojo.UserDownload;
import com.dahaiwuliang.code.server.*;
import com.dahaiwuliang.code.util.*;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import org.aspectj.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;


import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import static com.dahaiwuliang.code.util.Consts.MAIL_CODE_NAME;

@Controller
@RequestMapping( value = "/user")
public class UserController {
    @Autowired
    private UserServer userServer;

    @Autowired
    private ArticleService articleService;
    @Resource
   private JavaMailSender mailSender;

    @Autowired
    private CommentService commentService;
    @Autowired
    private ArticleIndex articleIndex;

    @Autowired
   private  UserDownloadService userDownloadService;
    @Autowired
    private MessageService messageService;

    @Value ("${imgFilePath}")
    private  String imgFilePath;
    /**
     *
     * @param user
     * @param bindingResult @Valid 和 BindingResult 是一一对应的，如果有多个@Valid，那么每个@Valid后面跟着的BindingResult就是这个@Valid的验证结果，顺序不能乱
     * @return
     */
    @ResponseBody
    @PostMapping("/register")
    public HashMap<String,Object> register(@Valid User user , BindingResult bindingResult){
        HashMap<String,Object> map=new HashMap<>();
        if (bindingResult.hasErrors()){
            map.put("success",false);
            map.put("errorInfo",bindingResult.getFieldError().getDefaultMessage());

        }else if(userServer.findByUserName(user.getUserName())!=null){
            map.put("success",false);
            map.put("errorInfo","用户名已存在");
        }else if(userServer.findByEmail(user.getEmail())!=null){
            map.put("success",false);
            map.put("errorInfo","邮箱已存在");}else {
            user.setRegistrationDate(new Date());
            user.setLatelyLoginTime(new Date());
            user.setHeadPortrait("tou.jpg");
            user.setPassword(CryptographyUtil.MD5(user.getPassword(),CryptographyUtil.SALT));
            userServer.save(user);
            map.put("success",true);
        }

        map.put("success",true);
        return map;
    }
    @ResponseBody
    @PostMapping("/login")
public Map<String,Object> login(User user, HttpSession httpSession){
    HashMap<String,Object> map=new HashMap<>();
    if (StringUtil.isEmpty(user.getUserName())){
        map.put("success",false);
        map.put("errorInfo","用户名不能为空");
    }else if (StringUtil.isEmpty(user.getPassword())){
        map.put("success",false);
        map.put("errorInfo","密码不能为空");
    }else{
        Subject subject=SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(user.getUserName(),CryptographyUtil.MD5(user.getPassword(),CryptographyUtil.SALT));
        try{
            subject.login(token);
            String userName=(String)SecurityUtils.getSubject().getPrincipal();
            User currentUlit=userServer.findByUserName(userName);
            if (currentUlit.isOff()){
                map.put("success",false);
                map.put("errorInfo","用户已经被封禁，请联系管理员!");
                subject.logout();
            }else {
                currentUlit.setLatelyLoginTime(new Date());
                userServer.save(currentUlit);
                //未读信息数
                Integer messageCount=messageService.getCountByUserId(currentUlit.getUserId());
                currentUlit.setMessageCount(messageCount);
                //失效资源1数
                Article article=new Article();
                article.setUseful(false);
                article.setUser(currentUlit);
                httpSession.setAttribute(Consts.UNUSEFUL_ARTICLE_COUNT,articleService.getCount(article,null,null,null));
                httpSession.setAttribute(Consts.CURRENT_USER,currentUlit);
                map.put("success",true);
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("errorInfo","用户或者密码错误");
        }
    }
    return map;
}
    @ResponseBody
    @PostMapping("/sendEmail")
    public Map<String,Object> sendEmail(String email, HttpSession httpSession){
        HashMap<String,Object> map=new HashMap<>();
        if (StringUtil.isEmpty(email)){
            map.put("success",false);
            map.put("errorInfo","邮箱不能为空");
            return  map;

        }
        User user=userServer.findByEmail(email);
        if (user ==null){
            map.put("success",false);
            map.put("errorInfo","邮箱不存在");
            return map;
        }
         String mailCode=StringUtil.getSixRandom();
        //发邮件
        SimpleMailMessage message=new SimpleMailMessage();
        message.setFrom("1362795253@qq.com");                        //发件人
        message.setTo(email);                                       //收件人
        message.setSubject("Java资源分享网-用户找回密码");         //主题
        message.setText("您本次的验证码是：" +mailCode);            //正文内容
        mailSender.send(message);
        System.out.println(mailCode);
        //将密码存到session
        httpSession.setAttribute(MAIL_CODE_NAME,mailCode);
        httpSession.setAttribute(Consts.USER_ID_NAME,user.getUserId());
        map.put("success",true);
        return map;
    }
    @ResponseBody
    @PostMapping("/checkYzm")
    public Map<String,Object> checkYzm(String yzm, HttpSession httpSession){
        HashMap<String,Object> map=new HashMap<>();
            if (StringUtil.isEmpty(yzm)){
                map.put("success",false);
                map.put("errorInfo","验证码不能为空");
                return  map;

        }
        String mailCode=(String)httpSession.getAttribute(Consts.MAIL_CODE_NAME);
        Integer UserId=(Integer)httpSession.getAttribute(Consts.USER_ID_NAME);

        if (!yzm.equals(mailCode)){
            map.put("success",false);
            map.put("errorInfo","验证码错误");
            return  map;
        }
        //给用户重置密码
        User user=userServer.findById(UserId);
        user.setPassword(CryptographyUtil.MD5(Consts.PASSWORD,CryptographyUtil.SALT));
        userServer.save(user);
        map.put("success",true);
        return map;}
    /**
     * 资源管理
     */
    @GetMapping("/articleManage")
    public String articleManage(){
       return "user/articleManage";
    }

    /**
     * 根据条件分页查询资源信息列表（只显示当前登录用户的资源）
     * @param
     * @param page
     * @param pageSize
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/articleList")
    public Map<String,Object> articleList(Article s_article,@RequestParam(value="page",required = false) Integer page,
                                          @RequestParam(value="limit",required = false) Integer pageSize,HttpSession session){
        Map<String,Object> map = new HashMap<>();
        User currentUser = (User) session.getAttribute(Consts.CURRENT_USER);
        s_article.setUser(currentUser);
        map.put("data",articleService.list(s_article,null,null,null,page,pageSize, Sort.Direction.DESC,"publishDate"));
        map.put("count",articleService.getCount(s_article,null,null,null));     //总计录数
        map.put("code",0);
        return map;
    }

    @RequestMapping("toAddArticle")
    public String toAddArticle(){
        return "user/addArticle";
    }

    /**
     * 添加或修改资源
     */
    @ResponseBody
    @PostMapping("/saveArticle")
    public Map<String,Object> saveArticle(Article article,HttpSession session) throws IOException {
        Map<String,Object> resultMap = new HashMap<>();
        if(article.getPoints()<0||article.getPoints()>10){
            resultMap.put("success",false);
            resultMap.put("erroInfo","积分超出正常区间！");
            return resultMap;
        }
        if(!CheckShareLinkEnableUtil.check(article.getDownload())){
            resultMap.put("success",false);
            resultMap.put("erroInfo","百度云分享链接已经失效，请重新发布！");
            return resultMap;
        }
        User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
         if(article.getArticleId()==null){               //添加资源
            article.setPublishDate(new Date());
            article.setUser(currentUser);
            if(article.getPoints()==0){         //积分为0时，设置为免费资源
                article.setFree(true);
            }
            article.setState(1);                //未审核状态
            article.setClick(new Random().nextInt(150)+50);         //设置点击数为50~200
            articleService.save(article);
            resultMap.put("success",true);
        }else{                              //修改资源
            Article oldArticle = articleService.getById(article.getArticleId());        //获取实体
            if(oldArticle.getUser().getUserId().intValue()==currentUser.getUserId().intValue()){        //只能修改自己的资源
                oldArticle.setName(article.getName());
                oldArticle.setArcType(article.getArcType());
                oldArticle.setDownload(article.getDownload());
                oldArticle.setPassword(article.getPassword());
                oldArticle.setKeywords(article.getKeywords());
                oldArticle.setDescription(article.getDescription());
                oldArticle.setContent(article.getContent());
                if(oldArticle.getState()==3){           //假如原先是未通过，用户点击修改，则重新审核，状态变成未审核
                    oldArticle.setState(1);
                }
                articleService.save(oldArticle);
                //更新时需要把审核已经通过的新资源信息放入lucene
                if(oldArticle.getState().intValue()==2){
                    articleIndex.updateIndex(oldArticle);     //更新索引
                }
                resultMap.put("success",true);
            }
        }

        return resultMap;
    }
    /**
     * 验证资源的发布者
     * @param articleId
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/checkArticleUser")
    public Map<String,Object> checkArticleUser(Integer articleId,HttpSession session){
        Map<String,Object> resultMap = new HashMap<>();
        User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
        Article article = articleService.getById(articleId);
        if(article.getUser().getUserId().intValue() == currentUser.getUserId().intValue()){
            resultMap.put("success",true);
        }else{
            resultMap.put("success",false);
            resultMap.put("erroInfo","您不是资源所有者，不能修改！");
        }
        return resultMap;
    }

    /**
     * 进入修改资源页面
     * @param articleId
     * @return
     */
    @GetMapping("/toEditArticle/{articleId}")
    public ModelAndView toEditArticle(@PathVariable(value="articleId",required = true) Integer articleId){
        ModelAndView mav = new ModelAndView();
        Article article = articleService.getById(articleId);
        mav.addObject("article",article);
        mav.setViewName("user/editArticle");
        return mav;
    }
    @ResponseBody
    @RequestMapping("articleDelete")
    public Map<String,Object> articleDelete(Integer articleId,HttpSession session){
        Map<String,Object> map =new HashMap<>();
        User user= (User) session.getAttribute(Consts.CURRENT_USER);
        Article article=articleService.getById(articleId);
        if (article.getUser().getUserId().intValue()==user.getUserId().intValue()){

            commentService.deleteByArticleId(articleId);
            articleService.delete(articleId);
            articleIndex.deleteIndex(String.valueOf(articleId));
            map.put("success",true);
        }else {
          map.put("success",false);
          map.put("erroInfo","您不是资源所有者，不能修改！");
        }
        return map;
    }


    /**
     * 判断资源是否被用户下载过
     * @param articleId
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/userDownloadExist")
    public  boolean userDownloadExist(Integer articleId,HttpSession session){
        User user= (User) session.getAttribute(Consts.CURRENT_USER);
        Integer count=userDownloadService.getCountByUserIdAndArticleId(user.getUserId(),articleId);

        if (count>0){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 判断积分是否足够下载资源
     * @param points
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/userDownloadEnough")
    public boolean userDownloadEnough(Integer points,HttpSession session){
        User user= (User) session.getAttribute(Consts.CURRENT_USER);
        if (user.getPoints()>points){
            return  true;
        }else {
            return false;
        }
    }
/**
 * 跳转到下载页面
 */
@RequestMapping(value = "/toDownLoadPage/{articleId}")
public  ModelAndView  toDownLoadPage(@PathVariable("articleId") Integer articleId,HttpSession session){
    Article article=articleService.getById(articleId);
    //查不到或者审核不通过，直接返回null
    if (article==null||article.getState().intValue()!=2){
        return null;
    }
    User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);
    //判断用户是否下载
    int count =userDownloadService.getCountByUserIdAndArticleId(currentUser.getUserId(),articleId);
    if (count==0){
        //没下载过
        if (!article.isFree()){
            //非免费资源
            if (currentUser.getPoints()-article.getPoints()<0){
                //积分不够
                return  null;
            }
            //扣除积分保存到数据库
            currentUser.setPoints(currentUser.getPoints()-article.getPoints());
            userServer.save(currentUser);
            //给资源分享人加积分
            User user=article.getUser();
            user.setPoints(user.getPoints()+article.getPoints());
            userServer.save(user);
        }
        //保存用户下载表
        UserDownload userDownload=new UserDownload();
        userDownload.setArticle(article);
        userDownload.setUser(currentUser);
        userDownload.setDownloadDate(new Date());
        userDownloadService.save(userDownload);
    }
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("article",article);
    modelAndView.setViewName("article/downloadPage");
    return  modelAndView;

}
/**
 * 判断是否是VIP
 */
@ResponseBody
@RequestMapping("/isVip")
public boolean isVip(HttpSession session){
    User user= (User) session.getAttribute(Consts.CURRENT_USER);
    return user.isVip();
}
    /**
     * 跳转到下载页面
     */
    @RequestMapping(value = "/toVipDownLoadPage/{articleId}")
    public  ModelAndView  toVipDownLoadPage(@PathVariable("articleId") Integer articleId,HttpSession session){
        Article article=articleService.getById(articleId);
        //查不到或者审核不通过，直接返回null
        if (article==null||article.getState().intValue()!=2){
            return null;
        }
        User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);
        if (!currentUser.isVip()){
            return null;
        }
        //判断用户是否下载
        int count =userDownloadService.getCountByUserIdAndArticleId(currentUser.getUserId(),articleId);
        if (count==0){
            //保存用户下载表
            UserDownload userDownload=new UserDownload();
            userDownload.setArticle(article);
            userDownload.setUser(currentUser);
            userDownload.setDownloadDate(new Date());
            userDownloadService.save(userDownload);
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("article",article);
        modelAndView.setViewName("article/downloadPage");
        return  modelAndView;

    }
    @GetMapping(value = "toUnUsefulArticleManage")
    public  String  toUnUserfulArticleCount(HttpSession session){
        this.unUsefulArticleCount(session);
        return "user/unUsefulArticleManage";
    }
    /**
     * 失效资源
     */
private  void unUsefulArticleCount(HttpSession session){
User user= (User) session.getAttribute(Consts.CURRENT_USER);
Article s_article=new Article();
s_article.setUser(user);
s_article.setFree(false);
session.setAttribute(Consts.UNUSEFUL_ARTICLE_COUNT,articleService.getCount(s_article,null,null,null));

}
   @ResponseBody
   @RequestMapping(value = "/modifyArticleShareLink")
  public Map<String,Object> modifyArticleShareLink(Article article,HttpSession session) throws IOException {
      Map<String,Object> map =new HashMap<>();
      if (CheckShareLinkEnableUtil.check(article.getDownload())){
          Article s_article=articleService.getById(article.getArticleId());
          User user= (User) session.getAttribute(Consts.CURRENT_USER);
          if (s_article.getUser().getUserId().intValue()==user.getUserId().intValue()){
              s_article.setDownload(article.getDownload());
              s_article.setPassword(article.getPassword());
              s_article.setUseful(true);
              articleService.save(s_article);
              map.put("success",true);
              this.unUsefulArticleCount(session);
          }else {
              map.put("success",false);
              map.put("errorInfo","这不是你的资源，瞎改什么");
          }

      }else {
          map.put("success",false);
          map.put("errorInfo","百度云连接错误，瞎改什么");
      }




    return map;
  }
    /**
     * 进入已下载资源列表
     */
    @GetMapping(value = "/toHaveDownloaded/{currentPage}")
    public  ModelAndView toHaveDownloaded(@PathVariable(value = "currentPage",required = false)Integer currentPage,HttpSession session){
        this.unUsefulArticleCount(session);
        ModelAndView mav=new ModelAndView();
        User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);

        Page<UserDownload> userDownloadPage=userDownloadService.list(currentUser.getUserId(),currentPage,Consts.PAGE_SIZE,Sort.Direction.DESC,"downloadDate");
        mav.addObject("userDownloadList",userDownloadPage.getContent());

        mav.addObject("pageStr",HTMLUtil.getPagation("/user/toHaveDownloaded",userDownloadPage.getTotalPages(),currentPage,"没有下载任何资源"));
        mav.setViewName("user/haveDownloaded");


        return mav;
    }

    /**
     * 进入已下载资源列表
     */
    @GetMapping(value = "/userMessage/{currentPage}")
    public  ModelAndView userMessage(@PathVariable(value = "currentPage",required = false)Integer currentPage,HttpSession session){
        this.unUsefulArticleCount(session);
        ModelAndView mav=new ModelAndView();
        User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);

        if (currentUser.getMessageCount()==null||currentUser.getMessageCount()>0){
            messageService.uodateState(currentUser.getUserId());
            currentUser.setMessageCount(0);
        }
        session.setAttribute(Consts.CURRENT_USER,currentUser);

        Page<Message> pag=messageService.List(currentUser.getUserId(),currentPage,Consts.PAGE_SIZE,Sort.Direction.DESC,"publishDate");
        mav.addObject("messageList",pag.getContent());

        mav.addObject("pageStr",HTMLUtil.getPagation("/user/userMessage",pag.getTotalPages(),currentPage,"没有任何系统信息"));
        mav.setViewName("user/userMessage");


        return mav;
    }
    /**
     * 我的主页
     */
    @GetMapping(value = "home")
    public  ModelAndView home(HttpSession session){
        this.unUsefulArticleCount(session);
        ModelAndView mav=new ModelAndView();
        User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);
        Page<UserDownload> userDownloadPage =userDownloadService.list(currentUser.getUserId(),1,Consts.PAGE_SIZE,Sort.Direction.DESC,"downloadDate");
         if (userDownloadPage.getTotalElements()>0){
             mav.addObject("userDownloadList",userDownloadPage.getContent());
         }
        Page<Message> pag=messageService.List(currentUser.getUserId(),1,Consts.PAGE_SIZE,Sort.Direction.DESC,"publishDate");
         if (pag.getTotalElements()>0){
             mav.addObject("messageList",pag.getContent());
         }
     mav.setViewName("user/home");
        return  mav;
    }

    /**
     * 上传头像
     */
    @ResponseBody
    @RequestMapping(value = "/updateHeadPortrait")
    public Map<String,Object> updateHeadPortrait(MultipartFile file,HttpSession session) throws IOException {
        Map<String,Object> map =new HashMap<>();
        if (!file.isEmpty()){
            //获取文件名
            String fileName=file.getOriginalFilename();
            //获取文件的后缀名
            String suffixName=fileName.substring(fileName.lastIndexOf("."));
            //新文件名
            String newFileName=DateUtil.getCurrentDateStr()+suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(),new File(imgFilePath+newFileName));
            map.put("success",true);
            map.put("imgName",newFileName);
            User user= (User) session.getAttribute(Consts.CURRENT_USER);
            user.setHeadPortrait(newFileName);
            userServer.save(user);
            session.setAttribute(Consts.CURRENT_USER,user);

        }
        return map;
    }

    /**
     * 用户中心
     * @param session
     * @return
     */
    @GetMapping(value = "userCenter")
    public  ModelAndView userCenter(HttpSession session){
        ModelAndView mav=new ModelAndView();
        this.toUnUserfulArticleCount(session);
        User user = (User) session.getAttribute(Consts.CURRENT_USER);
        mav.addObject("currentUser",user);
        mav.setViewName("user/userCenter");
        return  mav;
    }
    /**
     * 修改基本信息
     */
    @ResponseBody
    @RequestMapping(value = "/userUpdate")
    public Map<String,Object> userUpdate(User user ,HttpSession session){
     Map<String,Object> map=new HashMap<>();
     User oldUser= (User) session.getAttribute(Consts.CURRENT_USER);
     oldUser.setNickname(user.getNickname());
     oldUser.setSex(user.getSex());
     userServer.save(oldUser);
     session.setAttribute(Consts.CURRENT_USER,oldUser);
     map.put("success",true);
     return map;
    }
    /**
     * 修改密码
     */
    @ResponseBody
    @RequestMapping(value = "/updatePassword")
    public Map<String,Object> updatePassword(HttpSession session,String oldPassword,
                                            String newPassword){
        Map<String,Object> map=new HashMap<>();
        User currentUser= (User) session.getAttribute(Consts.CURRENT_USER);
        if (currentUser.getPassword().equals(CryptographyUtil.MD5(oldPassword,CryptographyUtil.SALT))){
            User oldUser=userServer.findById(currentUser.getUserId());
            oldUser.setPassword(CryptographyUtil.MD5(newPassword,CryptographyUtil.SALT));
            userServer.save(oldUser);
            session.setAttribute(Consts.CURRENT_USER,oldUser);
            map.put("success",true);
        }else {map.put("eorrorInfo","原密码错误");}


        return map;
    }
}































